package br.com.wai2008.socket.client;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * This class implements the execution for a client request through
 * socket. It starts connecting to a specific port and executes the 
 * process of send and receive messages.
 * 
 * @since 
 * 		September, 2008.
 * 
 * @version
 * 		WAI2008 - version 1.0
 * 
 * @author 
 * 		Andre Romero Goncales
 */
public class SocketClient {

	/**
	 * Connection to the socket.
	 */
	private Socket client;

	/**
	 * Send buffer.
	 */
	private BufferedWriter send;

	/**
	 * Receive buffer.
	 */
	private BufferedReader receive;

	/**
	 * Host Name to connect.
	 */
	private String host = null;

	/**
	 * Port Number to connect.
	 */
	private int port = 0;

	/**
	 * Timeout connection.
	 */
	private int timeout = 0;

	/**
	 * Constructor.
	 * 
	 * @param
	 * 		host Host Name to connect.
	 * @param
	 * 		port Port Number to connect.
	 * @param
	 * 		timeout Timeout connection.
	 */
	public SocketClient(String host, int port, int timeout) {
		this.host = host;
		this.port = port;
		this.timeout = timeout;
	}

	/**
	 * Start a request for connection.
	 * You may set the server port number and host name and server 
	 * timeout to the connection.
	 *  
	 * @throws
	 * 		IOException if an error occur while connect to the server.
	 * @throws
	 * 		UnknownHostException if unknown host name.
	 * @throws
	 * 		SocketException if timeout occurs.
	 */
	public void startConnection() throws UnknownHostException, IOException {
		System.out.println("[SocketClient] Establishing connection to client (" + this.host + ":" + 
				this.port + ")...");
		this.client = new Socket(this.host, this.port);
		this.client.setSoTimeout(this.timeout);
		System.out.println("[SocketClient] Connection established to client (" + this.host + ":" + 
				this.port + ")");
	   	this.getBuffer();
	}

	/**
	 * Get a send and receive buffers.
	 * 
	 * @throws
	 * 		IOException if the stream of output or input cannot be gotten.
	 */
	private void getBuffer() throws IOException {
		this.send = new BufferedWriter(new OutputStreamWriter(this.client.getOutputStream()));
		this.send.flush();
		this.receive = new BufferedReader(new InputStreamReader(this.client.getInputStream()));
	}

	/**
	 * Send a message to the server.
	 * 
	 * @param
	 * 		message message to be sent.
	 * 
	 * @throws
	 * 		IOException if the message cannot be sent.
	 */
	public void sendMessage(String message) throws IOException {
		System.out.println("[SocketClient] Sending Message: " + message);
	   	this.send.write(message);
	   	this.send.flush();
		System.out.println("[SocketClient] Message sent");
    }

	/**
	 * Receive a message to the server.
	 * 
	 * @return
	 * 		Message received.
	 * 
	 * @throws
	 * 		IOException if the message cannot be read.
	 */
	public String receiveMessage() throws IOException {
		System.out.println("[SocketClient] Receiving Message...");
		String message = this.receive.readLine();
		System.out.println("[SocketClient] Message Received: " + message);
		return message + "";
	}
	
	public void closeConnection() throws IOException {
		this.client.close();
	}
	
	public static void main(String[] args) throws UnknownHostException, IOException {
		for (int i = 0; i < 10; i++) {
			SocketClient sc = new SocketClient("localhost", 30000, 00000);
			sc.startConnection();
			sc.sendMessage("<SSProtocol><HDSerial>12345678</HDSerial>" +
					"<Network><ID>00:0F:3D:38:3F:85</ID><Signal>-81</Signal>" +
					"</Network></SSProtocol>\n");
			sc.receiveMessage();
		}
	}
	
}
